/**
 * @Author: Kritsu
 * @Date:   2021/11/12 12:08:24
 * @Last Modified by:   Kritsu
 * @Last Modified time: 2021/11/17 18:49:13
 */

import { values } from "lodash"

export interface BufferEntry {
    //BUFF力量%
    buff_str_per: number

    //BUFF智力%
    buff_int_per: number

    //BUFF物攻%
    buff_phyatk_per: number

    //BUFF魔攻%
    buff_magatk_per: number

    //BUFF独立%
    buff_indatk_per: number

    //BUFF力智固定值
    buff_intstr_add: number

    //BUFF三攻固定值
    buff_attack_add: number

    /**
     * buff等级增加
     */
    buff_level_add: number
    /**
     * 转职被动智力
     */
    passive_int_alter: number

    passive_alter_level_add: number

    /**
     * 觉醒力智增加量%
     */
    awake_intstr_per: number

    /**
     * 觉醒力智增加量
     */
    awake_intstr_add: number

    /**
     * 觉醒等级增加
     */
    awake_level_add: number

    /**
     * 觉醒被动力智
     */
    passive_int_awake: number

    /**
     * 转职被动体精
     */
    passive_vitspi_alter: number

    /**
     * 觉醒被动体精
     */
    passive_vitspi_awake: number

    [key: string]: number
}

interface BufferExtra {
    /**
     * BUFF三攻%
     */
    buff_triatk_per: number

    /**
     * BUFF力智%
     */
    buff_intstr_per: number

    passive_alter: number
}

export interface BufferEntryOptions extends Partial<BufferEntry & BufferExtra> {}

export interface KeyNumber {
    [key: string]: number
}

export function mergeBufferEntry(buffer_entry: BufferEntry, options: BufferEntryOptions = {}) {
    const new_entry = createBufferEntry(options)
    const keys = new Set<string>(Object.keys(buffer_entry).concat(Object.keys(new_entry)))
    for (let key of keys) {
        let oldValue = buffer_entry[key] ?? 0
        let newValue = new_entry[key] ?? 0
        let value = key.endsWith("_per") ? oldValue.perMulti(newValue) : oldValue.plus(newValue)
        buffer_entry[key] = value
    }
}

export function createBufferEntry(options: BufferEntryOptions = {}): BufferEntry {
    let buff_str_per = options.buff_str_per ?? 0
    let buff_int_per = options.buff_int_per ?? 0

    let buff_intstr_per = options.buff_intstr_per ?? 0

    if (buff_intstr_per > 0) {
        buff_str_per = buff_intstr_per.perMulti(buff_str_per)
        buff_int_per = buff_intstr_per.perMulti(buff_int_per)
    }

    let buff_indatk_per = options.buff_indatk_per ?? 0
    let buff_magatk_per = options.buff_magatk_per ?? 0
    let buff_phyatk_per = options.buff_phyatk_per ?? 0

    let buff_triatk_per = options.buff_triatk_per ?? 0

    if (buff_triatk_per > 0) {
        buff_indatk_per = buff_triatk_per.perMulti(buff_indatk_per)
        buff_magatk_per = buff_triatk_per.perMulti(buff_magatk_per)
        buff_phyatk_per = buff_triatk_per.perMulti(buff_phyatk_per)
    }

    let buff_intstr_add = options.buff_intstr_add ?? 0

    let buff_attack_add = options.buff_attack_add ?? 0

    let buff_level_add = options.buff_level_add ?? 0

    let awake_intstr_per = options.awake_intstr_per ?? 0

    let awake_intstr_add = options.awake_intstr_add ?? 0

    let awake_level_add = options.awake_level_add ?? 0

    let passive_int_alter = options.passive_int_alter ?? 0

    let passive_int_awake = options.passive_int_awake ?? 0

    let passive_alter_level_add = options.passive_alter_level_add ?? 0

    let passive_vitspi_alter = options.passive_vitspi_alter ?? 0

    let passive_vitspi_awake = options.passive_vitspi_awake ?? 0

    let passive_alter = options.passive_alter ?? 0

    if (passive_alter > 0) {
        passive_int_alter = passive_alter.plus(passive_int_alter)
        passive_vitspi_alter = passive_alter.plus(passive_vitspi_alter)
    }

    return {
        buff_str_per,
        buff_int_per,
        buff_magatk_per,
        buff_phyatk_per,
        buff_indatk_per,
        buff_intstr_add,
        buff_attack_add,
        buff_level_add,
        awake_intstr_per,
        awake_intstr_add,
        awake_level_add,
        passive_int_alter,
        passive_int_awake,
        passive_vitspi_alter,
        passive_vitspi_awake,
        passive_alter_level_add
    }
}
